/*
   BaseControl.cpp
   
   Copyright (C) 2006 LinuxOne, Inc. <Republic of korea>

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1
   of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   Lessor General Public License for more details.

   You should have received a copy of the GNU Lessor General Public
   License along with this library; if not, write to the Free Software
   Foundation, inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

   Hyunjin Kim <mgc521@linuxone.co.kr>

   LinuxOne, Inc., hereby disclaims all copylight
   written by Hyunjin Kim, 20 December 2006
*/

#include <services/BaseService.h>

namespace booyopos
{

namespace services
{

CBaseService::CBaseService()
{
	deviceServiceDescription="BooyoPOS Control Module";
	deviceServiceVersion=0;


	autoDisable=false;
	state=S_CLOSED;
	checkHealthText="";
	claimed=false;
	dataEventEnabled=false;
	deviceEnabled=0;
	freezeEvents=false;
	outputID=0;

	physicalDeviceDescription="";
	physicalDeviceName="";


	fd=-1;
	bOpen=false;
}

CBaseService::~CBaseService()
{
}

/* Properties */
std::string
CBaseService::GetCheckHealthText()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return checkHealthText;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

bool
CBaseService::GetClaimed()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return claimed;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

bool
CBaseService::GetDeviceEnabled()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return deviceEnabled;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

void
CBaseService::SetDeviceEnabled(bool deviceEnabled)
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		/* TO DO */
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

std::string
CBaseService::GetDeviceServiceDescription()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return deviceServiceDescription;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

int
CBaseService::GetDeviceServiceVersion()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return deviceServiceVersion;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

bool
CBaseService::GetFreezeEvents()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return freezeEvents;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

void
CBaseService::SetFreezeEvents(bool freezeEvents)
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		/* TO DO */
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

std::string
CBaseService::GetPhysicalDeviceDescription()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return physicalDeviceDescription;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

std::string
CBaseService::GetPhysicalDeviceName()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		return physicalDeviceName;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

int
CBaseService::GetState()
{
	try
	{
		if(!bOpen)
		{
			return state;
		}
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

/* Common Method */
void 
CBaseService::Claim(int timeout)
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		if(!claimed)
		   claimed=true;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

void 
CBaseService::Close()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		tcsetattr(fd, TCSANOW, &oldtermio);

		bOpen=false;
	}
	catch(CByException bye)
	{
		throw bye;
	}
	bOpen = false;
}

void 
CBaseService::CheckHealth(int level)
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		/* TO DO */
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

void
CBaseService::DirectIO(int command, int data, void* object)
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		/* TO DO */
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

int 
CBaseService::Open(std::string logicalDeviceName, EventCallbacks cb)
throw (CByException)
{
	std::string IOPort;
	int baurate;
	int iflag, oflag, cflag, lflag;

	try
	{
		if(bOpen)
		{
			throw CByException(E_ILLEGAL, "Device Control already open");
		}

		if(logicalDeviceName == "CP20C2L")
		{
			IOPort="/dev/ttyS5";
			baurate=B9600;
			iflag=IGNPAR | ICRNL;
			oflag=0;
			cflag=baurate | CRTSCTS | CS8 | CLOCAL;
			lflag&=!(ECHO);

			/* TEST //
			fd = open("/dev/ttyS5", O_RDWR | O_NOCTTY);
			if(fd == -1)
				return 1;

			tcgetattr(fd, &oldtermio);
			bzero(&newtermio, sizeof(newtermio));

			newtermio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL;
			newtermio.c_iflag = IGNPAR | ICRNL;
			newtermio.c_oflag = 0;
			newtermio.c_lflag &= (~ECHO);

			newtermio.c_cc[VTIME] = 0;
			newtermio.c_cc[VMIN] = 0;

			tcflush(fd, TCIOFLUSH);
			tcsetattr(fd, TCSANOW, &newtermio);

			write(fd, "asdf", 5);

			tcsetattr(fd, TCSANOW, &oldtermio);
			// HERE */
		}
		else if(logicalDeviceName == "VCB-355S")
		{
			IOPort="/dev/ttyS0";
			baurate=B9600;
			iflag=IGNPAR | ICRNL;
			oflag=0;
			cflag=baurate | CRTSCTS | CS8 | CLOCAL | CREAD;
			lflag=ICANON;
		}
		else if(logicalDeviceName == "TM-T88IV")
		{
			IOPort="/dev/ttyS0";
			baurate=B9600;
			iflag=IGNPAR | ICRNL;
			oflag=0;
			cflag=baurate | CRTSCTS | CS8 | CLOCAL | CREAD;
			lflag=ICANON;
		}
		else
		{
			IOPort="";
			baurate=B9600;
			iflag=IGNPAR | ICRNL;
			oflag=0;
			cflag=baurate | CRTSCTS | CS8 | CLOCAL | CREAD;
			lflag=ICANON;
		}

		fd = open(IOPort.c_str(), O_RDWR | O_NOCTTY);

		if(fd == -1)
			return 1;

		tcgetattr(fd, &oldtermio);
		bzero(&newtermio, sizeof(newtermio));

		newtermio.c_iflag = iflag;
		newtermio.c_oflag = oflag;
		newtermio.c_cflag = cflag;

		newtermio.c_lflag = lflag;

		newtermio.c_cc[VTIME] = 0;
		newtermio.c_cc[VMIN] = 0;

		tcflush(fd, TCIOFLUSH);
		tcsetattr(fd, TCSANOW, &newtermio);

		bOpen=true;

		return 0;
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

void 
CBaseService::Release()
throw (CByException)
{
	try
	{
		if(!bOpen)
		{
			throw CByException(E_CLOSED, "Device is not opened");
		}

		/* TO DO */
	}
	catch(CByException bye)
	{
		throw bye;
	}
}

} // namespace services

} // namespace booyopos
